#pragma once

#include "esp_err.h"
#include "esp_zigbee_core.h"
#include "zboss_api.h"
#include "esp_check.h"
#include "nvs_flash.h"
#include "nvs.h"

#ifdef __cplusplus
extern "C" {
#endif



/**
 * @brief 协调器启动完成后的回调函数类型
 */
typedef void (*zb_coordinator_start_cb_t)(void);

/**
 * @brief 子设备成功加入 Zigbee 网络时的回调函数类型
 *
 * @param short_addr 子设备的 16 位网络短地址
 */
typedef void (*zb_device_join_cb_t)(uint16_t short_addr,esp_zb_ieee_addr_t ieee_addr);

/**
 * @brief 子设备离开 Zigbee 网络时的回调函数类型（可选实现）
 *
 * @param short_addr 子设备的 16 位网络短地址
 */
typedef void (*zb_device_leave_cb_t)(uint16_t short_addr,esp_zb_ieee_addr_t ieee_addr);

/**
 * @brief 当收到子设备上报的 ZCL 指令数据时的回调函数类型
 *
 * @param short_addr 发送数据的子设备短地址
 * @param cluster_id ZCL 集群 ID（如 0x0006 表示 On/Off 集群）
 * @param cmd_id     ZCL 命令 ID（如 0x00 表示 OFF，0x01 表示 ON）
 * @param payload    原始负载数据指针
 * @param length     负载数据长度
 */
typedef void (*zb_zcl_receive_cb_t)(esp_zb_zcl_report_attr_message_t *msg);

 bool update_device_short_addr_if_exists(const uint8_t *ieee_addr, uint16_t device_short_addr);
 
#ifdef __cplusplus
}
#endif

/* Basic manufacturer information */
#define ESP_MANUFACTURER_NAME "\x09""ESPRESSIF"      /* Customized manufacturer name */
#define ESP_MODEL_IDENTIFIER "\x07"CONFIG_IDF_TARGET /* Customized model identifier */

/* Zigbee configuration */
#define MAX_CHILDREN                    10          /* the max amount of connected devices */
#define INSTALLCODE_POLICY_ENABLE       false    /* enable the install code policy for security */
#define ESP_ZB_GATEWAY_ENDPOINT        1          /* esp light switch device endpoint */
#define ESP_ZB_PRIMARY_CHANNEL_MASK    ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK  /* Zigbee primary channel mask use in the example */

#define ESP_ZB_ZC_CONFIG()                                                              \
    {                                                                                   \
        .esp_zb_role = ESP_ZB_DEVICE_TYPE_COORDINATOR,                                  \
        .install_code_policy = INSTALLCODE_POLICY_ENABLE,                               \
        .nwk_cfg.zczr_cfg = {                                                           \
            .max_children = MAX_CHILDREN,                                               \
        },                                                                              \
    }

#define ESP_ZB_DEFAULT_RADIO_CONFIG()                           \
    {                                                           \
        .radio_mode = ZB_RADIO_MODE_NATIVE,                     \
    }

#define ESP_ZB_DEFAULT_HOST_CONFIG()                            \
    {                                                           \
        .host_connection_mode = ZB_HOST_CONNECTION_MODE_NONE,   \
    }

typedef struct {
    esp_zb_ieee_addr_t ieee_addr;
    uint16_t short_addr;
    uint8_t  endpoint;
    bool     is_online;
    uint32_t last_seen_ms;
} zigbee_device_info_t;

#define MAX_DEVICES 16
static zigbee_device_info_t s_devices[MAX_DEVICES];
static uint8_t s_device_count = 0;
    
bool get_esp_zb_ieee_addr(uint16_t short_addr, char *out_str, size_t len);

zigbee_device_info_t *get_esp_zb_short(const char *ieee_str_in);

/**
 * @brief 初始化 Zigbee 协调器，启动 Zigbee 协议栈任务
 *
 * @return 初始化成功返回 ESP_OK，否则返回错误代码
 */
esp_err_t zigbee_manager_init(void);

/**
 * @brief 通用的 Zigbee ZCL 命令发送函数
 *
 * @param short_addr     目标设备的短地址
 * @param endpoint       目标设备端点（默认一般为 1）
 * @param cluster_id     ZCL 集群 ID（如 0x0006 表示 On/Off）
 * @param command_id     ZCL 命令 ID（如 0x01 表示 ON）
 * @param payload        数据负载指针（如无数据可传 NULL）
 * @param payload_len    数据长度（如无数据传 0）
 * @return esp_err_t     成功返回 ESP_OK
 */
esp_err_t zigbee_send_zcl_command(uint16_t short_addr, uint8_t endpoint,uint16_t cluster_id, uint8_t command_id,const uint8_t *payload);

/**
 * @brief 注册用户自定义的 Zigbee 回调函数
 *
 * @param on_start   协调器启动完成回调
 * @param on_join    子设备加入回调
 * @param on_leave   子设备离网回调（可为 NULL）
 * @param on_receive 接收子设备数据回调
 */
void zigbee_register_callbacks(zb_coordinator_start_cb_t on_start,
                               zb_device_join_cb_t on_join,
                               zb_device_leave_cb_t on_leave,
                               zb_zcl_receive_cb_t on_receive);

/**
 * @brief 检查指定短地址的子设备是否已存在于设备列表中
 *
 * @param short_addr 子设备的 16 位网络短地址
 * @return true      设备已存在（重复加入）
 * @return false     设备尚未加入，可添加到列表
 */
bool device_exists(uint16_t short_addr);

bool device_exists_ieee(const uint8_t *ieee_addr);

esp_err_t save_devices_to_nvs(void);